import { FC } from "react";
import {
	createBrowserRouter,
	NavigateOptions,
	RouterProvider,
	useLocation as useLocationT,
	useNavigate as useNavigateT
} from "react-router-dom";

import { RouteObject, routes, type TPath } from "@/router";
import Lazy from "@/router/components/Lazy";
import store from "@/store";
import { getUserInfoAction } from "@/store/modules/publicReducer";

export type TRouter = ReturnType<typeof createBrowserRouter>;

class Router {
	public router: TRouter;
	public Provider: FC;

	constructor(routes: RouteObject[]) {
		this.router = this.createRouter(routes);
		this.Provider = this.createProvider;
	}

	public createProvider = () => {
		return this.router ? <RouterProvider router={this.router} /> : null;
	};

	public createRouter = (routes: RouteObject[]) => {
		// const dispatch = useDispatch();
		return createBrowserRouter([
			{
				element: <Lazy module={() => import("@/App.tsx")} />,
				loader: async () => {
					await store.dispatch(getUserInfoAction());
					const { userInfo } = store.getState().public;
					return userInfo;
				},
				children: routes
			}
		]);
	};

	/**
	 * @description 根据路径获取当前路由对象
	 * @param path
	 * @param routes
	 */
	public searchRoute = (path: TPath, routes: RouteObject[] = []): RouteObject => {
		let route: RouteObject = {};
		for (const item of routes) {
			if (item.path === path) return item;
			if (item.children) {
				const res = this.searchRoute(path, item.children);
				if (Object.keys(res).length) route = res;
			}
		}
		return route;
	};

	public useNavigate = () => {
		const navigate = useNavigateT();
		return {
			navigate: (to: TPath, options?: NavigateOptions) => navigate(to, options)
		};
	};

	public useLocation = () => {
		const location = useLocationT();
		return location as typeof location & { pathname: TPath };
	};
}

export const { router, Provider, createRouter, searchRoute, useNavigate, useLocation } = new Router(routes);
